﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>


//template <class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;//sizeof...计算参数包里几个参数
//}
//int main()
//{
//	Print();
//	Print(1);
//	Print(1,1.1);
//	Print(1, 1.1,string("xxxxxxx"));
//
//	return 0;
//}
////////////////////////////////////////////////////////////// 
void ShowList()
{
	// 编译器时递归的终⽌条件，参数包是0个时，直接匹配这个函数 
	cout << endl;
}
template <class T, class ...Args>
void ShowList(T x, Args... args)
{
	cout << x << " ";
	// args是N个参数的参数包 
	// 调⽤ShowList，参数包的第⼀个传给x，剩下N-1传给第⼆个参数包 
	ShowList(args...);
}
// 编译时递归推导解析参数 
template <class ...Args>
void Print(Args... args)
{
	ShowList(args...);
}
int main()
{
	Print();
	Print(1);
	Print(1, string("xxxxx"));
	Print(1, string("xxxxx"), 2.2);
	return 0;
}
/////////////////////////////////////////////////////////////////
template <class T>
const T& GetArg(const T& x)
{
	cout << x << " ";
	return x;
}
template <class ...Args>
void Arguments(Args... args)
{}
template <class ...Args>
void Print(Args... args)
{
	// 注意GetArg必须返回或者到的对象，这样才能组成参数包给Arguments 
	Arguments(GetArg(args)...);
}
// 本质可以理解为编译器编译时，包的扩展模式 
// 将上⾯的函数模板扩展实例化为下⾯的函数 
// 是不是很抽象，C++11以后，只能说委员会的⼤佬设计语法思维跳跃得太厉害 
//void Print(int x, string y, double z)
//{
// Arguments(GetArg(x), GetArg(y), GetArg(z));
//}
int main()
{
	Print(1, string("xxxxx"), 2.2);
	return 0;
}
